#!/usr/bin/env python
# encoding: utf-8
# @author: Lin Han
# @contact: voldemort22@126.com
# @file: deprecated_app.py
# @time: 2021/3/23 15:33
# @desc:
import json

from fastapi import APIRouter, BackgroundTasks

from application.history_clamp.crud import keyword_search_history_clamp, generate_history_clamp_data
from application.history_clamp.queryModels import UploadHistoryClampModel
from background.background_update import update_01
from cache.redis_pool import get_redis
from models.queryModels import MultipleConditionQueryHistoryClamps, LockFlagQuery, UpdateHistoryClampConfigData, UpdateHistoryClamp
from models.responseModels import ResponseDict
from utils.mongo_tools import update_mongo_value, retrieve_all_mongo_values, create_one_mongo_value, retrieve_one_mongo_value, delete_mongo_value, history_clamp_number_generator
from views.configs import *
from views.crud import separate_page, send_to_message_queue, sort_redis_result

history_clamp_router = APIRouter(
    prefix="/api/history_clamp",
    tags=["history_clamp"],
)


@history_clamp_router.get("/v1/history_clamp_catia_file")
async def get_history_clamp_catia_file(number: str):
    """
    返回历史夹具的catia模型在OSS上的地址

    - :param number: 编号
    - :return:
    """
    model = {"data": ""}
    original_data = retrieve_one_mongo_value(number, database_name=MONGO_DATABASE_NAME, collection_name=HISTORY_CLAMP_COLLECTION)
    try:
        model["data"] = {
            "name": original_data[0]['name'],
            "path": original_data[0]["file"][CATPART_OSS_ADDRESS],
        }
    except:
        model["status"] = 0
    model["status"] = 1
    return model


@history_clamp_router.get("/v1/history_clamp_gltf_file")
def get_history_clamp_gltf_file(number: str):
    """
    Deprecated.
    返回历史夹具的gltf模型在OSS上的地址

    - :param number: 编号
    - :return:
    """
    model = {"data": ""}
    original_data = retrieve_one_mongo_value(
        number,
        collection_name=HISTORY_CLAMP_COLLECTION,
    )
    try:
        model["data"] = original_data[0]["file"][GLTF_OSS_ADDRESS]
        model["status"] = 1
    except:
        model["status"] = 0
    return model


@history_clamp_router.put("/v2/history_clamp_flag_tag")
def update_history_clamp_flag_tag_v2(queryModel: LockFlagQuery):
    """
    ## 锁定夹具状态
    锁定或解锁夹具状态，要对夹具进行编辑前必须解锁。

    - :param queryModel: 该类包含夹具的唯一编码number以及布尔类型字段isFlag
    - :return:
    """
    # First delete the corresponded data in redis.
    update_mongo_value(
        filter_condition={"number": queryModel.number},
        new_value={"$set": {"isFlag": queryModel.isFlag}},
        collection_name=HISTORY_CLAMP_COLLECTION,
    )

    original_data = retrieve_one_mongo_value(queryModel.number, collection_name=HISTORY_CLAMP_COLLECTION)[0]
    try:
        redis_connection = get_redis(port=HISTORY_CLAMP_REDIS_PORT)
        redis_connection.set(queryModel.number, json.dumps(original_data))
    except:
        pass

    model = {
        "status": 1,
        "data": True,
    }
    return model


@history_clamp_router.get("/v2/history_clamp_config")
def get_history_clamp_drop_down_box_v2():
    """
    ## 历史夹具下拉框数据。
    - 查询历史夹具配置表里的信息。

    - :return:
    """
    # 先把redis中的符合历史夹具的key都拿出来
    redis_connection = get_redis(port=HISTORY_CLAMP_REDIS_PORT)
    try:
        history_clamp_config = redis_connection.get("history_clamp_config")
        config_data = json.loads(history_clamp_config)
    except:
        config_data = retrieve_all_mongo_values(
            {"type": "clamp"},
            collection_name="config",
        )[0][CONFIG_DATA]
        # 把mongo中查到的数据set到redis数据库中
        redis_connection.set("history_clamp_config", json.dumps(config_data))

    model = {"data": config_data, "status": 1}
    return model


@history_clamp_router.put("/v2/history_clamp_config")
def update_history_clamp_config(oneInfo: UpdateHistoryClampConfigData):
    """
    ## 更新历史夹具配置表里的信息
    注意不是模型表里的。

    - :param oneInfo:
    - :return:
    """
    redis_connection = get_redis(port=HISTORY_CLAMP_REDIS_PORT)
    configData = retrieve_all_mongo_values({"type": "clamp"}, collection_name="config")[0]['configData']
    if oneInfo.standard is not None:
        configData['standard'] = oneInfo.standard
    if oneInfo.area is not None:
        configData['area'] = oneInfo.area
    if oneInfo.pinType is not None:
        configData['pinType'] = oneInfo.pinType
    if oneInfo.rpsType is not None:
        configData['rpsType'] = oneInfo.rpsType
    updateInfo = {"$set": {"configData": configData}}
    update_mongo_value(
        {"type": "clamp"},
        updateInfo,
        collection_name="config",
    )

    redis_connection.set("history_clamp_config", json.dumps(configData))

    model = {"data": True, "status": 1}
    return model


@history_clamp_router.post("/v4/history_clamps", response_model=ResponseDict)
def multiple_condition_query_history_clamps_v4(queryModel: MultipleConditionQueryHistoryClamps, background_tasks: BackgroundTasks):
    """
    ## 列表查询多条历史夹具。输入参数所有字段均可为空。
    历史夹具数据中新增了一个isSceneBinded布尔字段。

    - :param queryModel: 该对象包含isFlag, isFeature以及可为空的厂家标准standard
    - :return:
    """
    redis_connection = get_redis(port=HISTORY_CLAMP_REDIS_PORT)
    try:
        history_clamp_number_list = redis_connection.get("history_clamp")
        history_clamp_number_list = json.loads(history_clamp_number_list)
        history_clamp_list = redis_connection.mget(*history_clamp_number_list)
        result = [json.loads(i) for i in history_clamp_list]
    except:
        result = retrieve_all_mongo_values({}, collection_name=HISTORY_CLAMP_COLLECTION)
        background_tasks.add_task(update_01)

    result = keyword_search_history_clamp(queryModel, result)
    if len(result) > 0:
        if queryModel.isSceneBinded is not None:
            result = [i for i in result if i["isSceneBinded"] == queryModel.isSceneBinded]
            total = len(result)
            result = separate_page(result, page=queryModel.page, pagesize=queryModel.pagesize)
        else:
            total = len(result)
            result = separate_page(result, page=queryModel.page, pagesize=queryModel.pagesize)
        model = {
            "data": {
                "result": result,
                "total": total,
            },
            "status": 1,
        }
    else:
        model = {"data": {}, "status": 0}
    return model


@history_clamp_router.post("/v3/history_clamp")
def upload_v3(queryModel: UploadHistoryClampModel):
    """
    ## 上传历史夹具V3版
    上传历史夹具的catpart格式文件并转化stp, stl, glb的接口，前端传过来的只有夹具和工件（可选）的OSS地址，这里需要在数据库里生成一条数据，把这些地址存到这条数据里。

    - :return:
    """
    redis_connection = get_redis(port=HISTORY_CLAMP_REDIS_PORT)
    number = history_clamp_number_generator()
    clampModel = generate_history_clamp_data(
        number,
        file_path=queryModel.catpartAliOssAddress,
        workpiece_file_path=queryModel.workpieceCatpartAliOssAddress,
    )

    redis_connection.set(clampModel["number"], json.dumps(clampModel))

    create_one_mongo_value(clampModel, collection_name=HISTORY_CLAMP_COLLECTION)
    send_to_message_queue(number)

    model = {"data": number, "status": 1}
    return model


@history_clamp_router.put("/v3/history_clamp")
def update_history_clamp_v3(queryModel: UpdateHistoryClamp):
    """
    ## 更新历史夹具模型表里每个模型的Tag属性。
    - :param queryModel: tag里面需要的所有属性，以及number号用以标明是哪套夹具。
    - :return:
    """
    redis_connection = get_redis(port=HISTORY_CLAMP_REDIS_PORT)

    tag = retrieve_all_mongo_values(
        {"number": queryModel.number},
        collection_name=HISTORY_CLAMP_COLLECTION,
    )[0]['tag']
    for i in queryModel.dict().keys():
        if i == "number":
            continue
        if queryModel.dict()[i] is not None:
            tag[i] = queryModel.dict()[i]

    update_mongo_value(
        {"number": queryModel.number},
        {"$set": {"tag": tag}},
        collection_name=HISTORY_CLAMP_COLLECTION,
    )

    try:
        original_data = retrieve_one_mongo_value(queryModel.number, collection_name=HISTORY_CLAMP_COLLECTION)[0]
        redis_connection.set(queryModel.number, json.dumps(original_data))
    except:
        pass

    model = {"data": True, "status": 1}
    return model


@history_clamp_router.get("/v3/history_clamp")
def retrieve_history_clamp_v3(number: str):
    """
    ## 返回一条历史夹具的完整信息V2版
    返回值中多一个参数page，告知前端这条数据在第几个page（按pagesize为10的情况）。

    - :param number: 编号
    - :return:
    """
    redis_connection = get_redis(port=HISTORY_CLAMP_REDIS_PORT)
    model = {"data": {}}

    # take out the data in redis
    try:
        try:
            history_clamp = redis_connection.get(number)
            data = json.loads(history_clamp)
        except:
            # if reach here then means no data in redis. Now go to mongo.
            data = retrieve_one_mongo_value(number, collection_name=HISTORY_CLAMP_COLLECTION)[0]
            # then add it into redis
            redis_connection.set(number, json.dumps(data))
            history_clamp_number_list = redis_connection.get("history_clamp")
            history_clamp_number_list = json.loads(history_clamp_number_list)
            history_clamp_number_list.append(number)
            redis_connection.set("history_clamp", json.dumps(history_clamp_number_list))
        model["data"] = data

        sort_redis_result(model=model, number=number, data_type="history_clamp", redis_connection=redis_connection)
        model["status"] = 1
    except:
        model["status"] = 0
    return model


@history_clamp_router.delete("/v3/history_clamp")
def delete_history_clamp_v3(number: str, background_task: BackgroundTasks):
    """
    ## 删除一套夹具数据
    直接去mongo中删除，然后丢一个后台任务：重启历史夹具的docker，并把数据从mongo中拷入。

    - :param number: 夹具的number
    - :return:
    """
    model = {"data": False}
    try:
        result = delete_mongo_value(number, collection_name=HISTORY_CLAMP_COLLECTION)
        background_task.add_task(update_01)
        if result.deleted_count > 0:
            model["data"] = True
            model["status"] = 1
        else:
            model["status"] = 0
    except:
        model["status"] = 0
    return model
